/*
 * VBM(Video Buffer Manager) test.
 *
 * Copyright (C) 2014 Ingenic Semiconductor Co.,Ltd
 * Author: Zoro <ykli@ingenic.cn>
 */

#include <unistd.h>
#include <sys/time.h>

#include <CUnit/CUnit.h>
#include <CUnit/Automated.h>
#include <CUnit/Basic.h>
#include <CUnit/Console.h>

#include <constraints.h>
#include <imp/imp_common.h>
#include <imp/imp_log.h>
#include <imp/imp_system.h>
#include <imp/imp_utils.h>

#include <system/vbm.h>

#define TAG "VBMTest"

VBMPoolConfig pool0_config;

static int test_vbm_getFrame(IMPFrameInfo *frame, void *pri)
{
	static int vb_index = 0;
	frame->index = vb_index++ % pool0_config.nr_buffers;

	struct timeval timestamp;
	gettimeofday(&timestamp, NULL);
	frame->timeStamp = (int64_t)((int64_t)timestamp.tv_sec * 1000000 + (int64_t)timestamp.tv_usec);

	IMP_LOG_DBG(TAG, "%s():%d\n", __func__, __LINE__);
	return 0;
}

static int test_vbm_releaseFrame(IMPFrameInfo *frame, void *pri)
{
	IMP_LOG_DBG(TAG, "%s():%d\n", __func__, __LINE__);

	return 0;
}

static void VBM_test_1()
{
	int ret;
	VBMInterface interface;
	interface.getFrame = test_vbm_getFrame;
	interface.releaseFrame = test_vbm_releaseFrame;

	ret = VBMInit(&interface);
	if (ret < 0) {
		IMP_LOG_ERR(TAG, "VBMInit() failed\n");
		CU_FAIL();
	}

	pool0_config.fmt.fmt.pix.width = 1920;
	pool0_config.fmt.fmt.pix.height = 1080;
	pool0_config.fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12;
	pool0_config.fmt.fmt.pix.sizeimage = 1920 * 1080 * 3 / 2;
	pool0_config.nr_buffers = 4;

	ret = VBMCreatePoll(0, &pool0_config, NULL);
	if (ret < 0) {
		IMP_LOG_ERR(TAG, "VBMCreatePoll(0) failed\n");
		CU_FAIL();
		goto exit;
	}

	VBMFillPoll(0);
	IMPFrameInfo *frame;

#define DUMP_FRAME(frame)												\
	IMP_LOG_DBG(TAG, "frame-%d p:%d v:%08x p:%08x w:%d h%d fmt:%s s:%d t:%llu\n", \
				frame->index,											\
				frame->pool_idx,											\
				frame->virAddr,											\
				frame->phyAddr,											\
				frame->width,											\
				frame->height,											\
				IMPPixfmtToString(frame->pixfmt),						\
				frame->size,											\
				frame->timeStamp);
	VBMGetFrame(0, &frame);
	DUMP_FRAME(frame);
	VBMReleaseFrame(frame);
	usleep(100000);

	VBMGetFrame(0, &frame);
	DUMP_FRAME(frame);
	VBMReleaseFrame(frame);
	usleep(100000);

	VBMGetFrame(0, &frame);
	DUMP_FRAME(frame);
	VBMReleaseFrame(frame);
	usleep(100000);

	VBMGetFrame(0, &frame);
	DUMP_FRAME(frame);
	VBMReleaseFrame(frame);

	VBMFlushPoll(0);

	ret = VBMDestroyPoll(0);
	if (ret < 0) {
		IMP_LOG_ERR(TAG, "VBMDestroyPoll(0) failed\n");
		CU_FAIL();
		goto exit;
	}

	CU_PASS();
exit:
	VBMExit();
}

CU_TestInfo VBMTest[] = {
	{"VBM Init and Exit test", VBM_test_1},
	CU_TEST_INFO_NULL,
};
